package cn.com.basic.framework.aliyun.oss.upload;

import cn.com.basic.framework.aliyun.oss.OSSManager;
import cn.hutool.core.lang.Assert;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.net.URL;

/**
 * 简单上传指的是使用OSS API中的PutObject方法上传单个文件（Object）
 * <p>
 * 简单上传分为流式上传和文件上传。流式上传使用InputStream作为文件的数据源。文件上传使用本地文件作为OSS文件的数据源。
 *
 * @author zhuxj
 */
public class SimpleUploader extends Uploader {


    public SimpleUploader(OSSManager ossManager) {
        super(ossManager);
    }


    /**
     * 上传字符串
     *
     * @param content    等待上传内容
     * @param bucketName 目标存储空间
     * @param objName    上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
     * @return {@link PutObjectResult}
     */
    public PutObjectResult uploadString(String content, String bucketName, String objName) {
        Assert.isTrue(StringUtils.isNotEmpty(content), "content cannot be empty");
        return uploadBytes(content.getBytes(), bucketName, objName);
    }

    /**
     * 上传字节数组
     *
     * @param content    等待上传的字节内容
     * @param bucketName 目标存储空间
     * @param objName    上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
     * @return {@link PutObjectResult}
     */
    public PutObjectResult uploadBytes(byte[] content, String bucketName, String objName) {
        Assert.isTrue(this.ossManager.getOss() != null, "oss client cannot be null");
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objName, new ByteArrayInputStream(content));
        return this.ossManager.getOss().putObject(putObjectRequest);
    }

    /**
     * 上传流
     *
     * @param is         inputStream
     * @param bucketName 目标存储空间
     * @param objName    上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
     * @return {@link PutObjectResult}
     */
    public PutObjectResult uploadStream(InputStream is, String bucketName, String objName) {
        Assert.isTrue(is != null, "stream cannot be null");
        Assert.isTrue(this.ossManager.getOss() != null, "oss client cannot be null");
        return this.ossManager.getOss().putObject(bucketName, objName, is);
    }

    /**
     * 上传网络流
     *
     * @param url        网址url遵守http（https）协议
     * @param bucketName 目标存储空间
     * @param objName    上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
     * @return {@link PutObjectResult}
     * @throws IOException IO异常
     */
    public PutObjectResult uploadNetStream(String url, String bucketName, String objName) throws IOException {
        Assert.isTrue(StringUtils.isNotEmpty(url) && url.startsWith("http"), "only support url with 'http' or 'https' protocol");
        return uploadStream(new URL(url).openStream(), bucketName, objName);
    }

    /**
     * 上传文件流
     *
     * @param fileInputStream 文件流
     * @param bucketName      目标存储空间
     * @param objName         上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
     * @return {@link PutObjectResult}
     */
    public PutObjectResult uploadFileStream(FileInputStream fileInputStream, String bucketName, String objName) {
        return uploadStream(fileInputStream, bucketName, objName);
    }

    /**
     * 上传文件
     *
     * @param file       待上传文件
     * @param bucketName 目标存储空间
     * @param objName    上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
     * @return {@link PutObjectResult}
     */
    public PutObjectResult uploadFile(File file, String bucketName, String objName) {
        Assert.isTrue(file != null, "file cannot be null");
        Assert.isTrue(this.ossManager.getOss() != null, "oss client cannot be null");
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objName, file);
        return this.ossManager.getOss().putObject(putObjectRequest);
    }
}
